class MyArray<T> {
    //创建一个T类型数组
    //public T[] array = (T[])new Object[10];
    public Object[] array = new Object[10];
    //创建一个T类型方法
    public void setValue(int pos,T val) {
            array[pos] = val;
    }
    //返回一个T类型
    public T getValue(int pos) {
            return (T)array[pos];
    }
}
public class Test {
    public static void main(String[] args) {
        //泛型
        MyArray<String>  myArray = new MyArray<>();
        myArray.setValue(0,"秦博");
        myArray.setValue(1,"是");
        myArray.setValue(2,"大帅哥");
        String str = myArray.getValue(2);
        System.out.println(str);
    }
    public static void main3(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);//true
        Integer c = 200;
        Integer d = 200;
        System.out.println(c == d);//false
        //因为整个过程发生了装箱，装箱本质上是调用了Integer.valueOf()这个方法
        //在这个方法实现中 会有一个cache[]的缓存数组 当装箱范围在缓存数组范围内(-127 - 128共256个整型值)时，会在数组相同位置，提取。
        //当大于范围时 就会返回一个new Integer(i)类型。导致不相等。
    }
    public static void main2(String[] args) {
        //包装类型 ：基本类型中
        //除了int 类型 和char 类型 包装类型分别是 Integer Character 其他均是首字母大写 其他均不变
        //有包装类型的意义更多的是为了 变成一个包装类 可以调用更多的包装方法 这样子就可以提高效率

        //装箱/装包: 变为包装类型
        int a = 10;
        //Integer aa = a;//自动装箱
        Integer aa = Integer.valueOf(a);//显示装箱 通过类名调用方法把a装箱为Integer包装类
        //拆箱/拆包:变成普通类型
        Integer aaa  = new Integer(10);
        //int aaaa = aaa;//自动拆箱
        int aaaa = aaa.intValue();//通过调用intValue方法进行拆箱
        double aaaaa = aaa.doubleValue();//可以拆包为任意类型

        System.out.println(aa);
        System.out.println(aaaa);
        System.out.println(aaaaa);
    }
    public static void main1(String[] args) {
        //时间和空间复杂度 --衡量一个算法的好坏
        //时间看一个算法运行速度 空间看一个算法需要的额空间

        //时间复杂度是一个数学函数
        //一个算法基本操作次数 就是它的时间复杂度 使用 F(N)表示

        //大O的渐进表达式O(时间复杂度)
        //推导大O阶方法
        //1.如果基本操作次数中有常数 则将常数转化为1
        //2.只保留最高此项 其他均忽略不计
        //3.如果存在最高项且相乘常数不为1，则把相乘常数转化为1

        //时间复杂度
        //最好情况下 最坏情况下 平均情况下
        //最好：任何输入规模的最小运行次数(1次就完成)
        //平均:任何输入规模的期望运行次数(N/2次完成)
        //最坏：任何输入规模的最大运行次数(最后一次完成)

        //事例

        // 计算func2的时间复杂度？
/*        void func2(int N) {
            int count = 0;
            for (int k = 0; k < 2 * N ; k++) {
                count++;
            }
            int M = 10;
            while ((M--) > 0) {
                count++;
            }
            System.out.println(count);
        }*/
        //复杂度= 2 * N + 10 = 2 * N + 1 =  2 * N = N O(N)

        //计算func3的时间复杂度？
        //void func3(int N, int M) {
        //int count = 0;
        //for (int k = 0; k < M; k++) {
        //count++;
        //}
        //for (int k = 0; k < N ; k++) {
        //count++;
        //}
        //System.out.println(count);
        //}
        //复杂度 = M + N  O(M + N)

        // 计算func4的时间复杂度？
        /*void func4(int N) {
            int count = 0;
            for (int k = 0; k < 100; k++) {
                count++;
            }
            System.out.println(count);
        }*/
        //复杂度 = 100 = 1     O(1)

        // 计算bubbleSort的时间复杂度？
        // 计算bubbleSort的时间复杂度？
/*        void bubbleSort(int[] array) {
            for (int end = array.length; end > 0; end--) {
                boolean sorted = true;
                for (int i = 1; i < end; i++) {
                    if (array[i - 1] > array[i]) {
                        Swap(array, i - 1, i);
                        sorted = false;
                    }
                }
                if (sorted == true) {
                    break;
                }
            }
        }*/
        //复杂度 = (n - 1) + (n - 2) + ... + 3 + 2 + 1(符合等差数列求和) = ((1 + (n - 1)) * (n -1))/2
       //= (n ^ 2)/2 - (n)/2 = n ^ 2    O(n ^ 2)

        // 计算binarySearch的时间复杂度？
/*        int binarySearch(int[] array, int value) {
            int begin = 0;
            int end = array.length - 1;
            while (begin <= end) {
                int mid = begin + ((end-begin) / 2);
                if (array[mid] < value)
                    begin = mid + 1;
                else if (array[mid] > value)
                    end = mid - 1;
                else
                    return mid;
            }
            return -1;
        }*/
        //复杂度 = n + n / 2 + n / 4 + ...n/2^x = 1 可得 O(log2^x) N= log2^x

        // 计算阶乘递归factorial的时间复杂度？
//        long factorial(int N) {
//            return N < 2 ? N : factorial(N-1) * N;
//        }
        //复杂度 =  递归次数 * 每次递归后的执行次数 = N,N - 1,N - 2....1(每次都需要与2比较 共N次)
        //* 三目运算符(只是一个运算 不是循环 所以为1) = N * 1 = N O(N)

        // 计算斐波那契递归fibonacci的时间复杂度？
//        int fibonacci(int N) {
//            return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
//        }
        //复杂度 = 递归次数 * 每次递归后执行次数 = 1 + 2 + 4....+  2^N-1(符合等比数列) * 1(只进行了三目运算)
        //Sn=a1(1-q^n)/(1-q)（q≠1) * 1 = (1 * (1 - 2 ^ N))/(1 - 2)  * 1 = 2 ^ N O(2 ^ N)

        //空间复杂度：执行算法时 临时占用存储空间大小的量度 使用大O渐进表示法

        // 计算bubbleSort的空间复杂度？
//        void bubbleSort(int[] array) {
//            for (int end = array.length; end > 0; end--) {
//                boolean sorted = true;
//                for (int i = 1; i < end; i++) {
//                    if (array[i - 1] > array[i]) {
//                        Swap(array, i - 1, i);
//                        sorted = false;
//                    }
//                }
//                if (sorted == true) {
//                    break;
//                }
                //空间复杂度 = 没有开辟临时空间 O(1)

        // 计算fibonacci的空间复杂度？
//        int[] fibonacci(int n) {
//            long[] fibArray = new long[n + 1];
//            fibArray[0] = 0;
//            fibArray[1] = 1;
//            for (int i = 2; i <= n ; i++) {
//                fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
//            }
//            return fibArray;
//        }
        //空间复杂度 = 每次动态开辟一个三方数组进行存储之和的一个空间 共开普N次 O(N)

        // 计算阶乘递归Factorial的空间复杂度？
//        long factorial(int N) {
//            return N < 2 ? N : factorial(N-1)*N;
//        }
        //空间复杂度 = 每次递归都会开辟一个空间 递归N次 O(N)
    }
}
